package com.pipe.servicepipe.config;

import com.pipe.servicepipe.util.JwtTokenUtil;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpStatus;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.logout.HttpStatusReturningLogoutSuccessHandler;

/**
 * @ClassName WebSecurityConfig
 * @Author HETAO
 * @Date 2020/7/16 10:50
 */
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //防止iframe
        http.headers().frameOptions().disable();


        ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry =
                http.authorizeRequests();
        /** 请求白名单*/
        ignoreUrlsConfig().getUrls().parallelStream().forEach(item -> registry.antMatchers(item).permitAll());
        /** 其他所有的请求都需要校验*/
        registry.and().authorizeRequests().anyRequest().authenticated();

        /** 关闭csf  并登录支持*/
        registry.and()
                .csrf()
                .disable()
                .formLogin()
                .loginPage("/pages/login.html")
                .successForwardUrl("/index.html")
              // 自定义权限拒绝处理类
                 .and()
                 .exceptionHandling()
                // .accessDeniedHandler(restfulAccessDeniedHandler())
                // .authenticationEntryPoint(restAuthenticationEntryPoint())
                // 自定义权限拦截器JWT过滤器
                .and()
                .addFilterBefore(jwtAuthenticationTokenFilter(), UsernamePasswordAuthenticationFilter.class);
        /** 提供注销支持*/
        registry.and().logout()
                /** 注销成功后 返回码 200 */
                .logoutSuccessHandler(new HttpStatusReturningLogoutSuccessHandler(HttpStatus.CREATED))
                /** 注销后是否删除session*/
                .invalidateHttpSession(true)
                /** 注销后删除名为pipeUser的cookie*/
                .deleteCookies("pipe");
    }


    @Bean
    public JwtTokenUtil jwtTokenUtil() {
        return new JwtTokenUtil();
    }

    /**
     * 从数据库中拿用户  并且用 BCryptPasswordEncoder加密
     * @param auth
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService())
                .passwordEncoder(passwordEncoder());
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public IgnoreUrlsConfig ignoreUrlsConfig() {
        return new IgnoreUrlsConfig();
    }


    @Bean
    public RestfulAccessDeniedHandler restfulAccessDeniedHandler() {
        return new RestfulAccessDeniedHandler();
    }

    @Bean
    public RestAuthenticationEntryPoint restAuthenticationEntryPoint() {
        return new RestAuthenticationEntryPoint();
    }

    @Bean
    public JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter() {
        return new JwtAuthenticationTokenFilter();
    }


}
